package jp.dodododo.aop.config;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import jp.dodododo.aop.Aspect;
import jp.dodododo.aop.Aspects;
import jp.dodododo.aop.annotation.Enhance;
import jp.dodododo.aop.impl.AspectsImpl;

@Enhance(false)
public class AspectConfigs {
	private static final String DEFAULT_CONFIG_PATH = "aspect.xml";

	private static final String CONFIG_PROPERTY_KEY = "samurai.aop.config";

	private static final String configPath = System.getProperty(CONFIG_PROPERTY_KEY) != null ? System.getProperty(CONFIG_PROPERTY_KEY)
			: DEFAULT_CONFIG_PATH;

	private static final Map<ClassLoader, Aspects> ASPECTS = new WeakHashMap<ClassLoader, Aspects>();

	public static Aspects getAspects() {
		return getAspects(Thread.currentThread().getContextClassLoader());
	}

	public static Aspects getAspects(ClassLoader loader) {
		Aspects aspects;
		if (ASPECTS.containsKey(loader) == false) {
			aspects = new AspectConfigBuilder().build(loader, configPath);
			if (aspects == null) {
				aspects = new AspectsImpl();
			}
			ASPECTS.put(loader, aspects);
		} else {
			aspects = ASPECTS.get(loader);
		}
		return aspects;
	}

	public static Aspect getAspectDef(String targetClassName) {
		return getAspectDef(Thread.currentThread().getContextClassLoader(), targetClassName);
	}

	public static Aspect getAspectDef(ClassLoader loader, String targetClassName) {
		Aspects aspects = getAspects(loader);
		if (aspects == null) {
			return null;
		}
		List<Aspect> aspectList = aspects.getAspectList();
		for (Iterator<Aspect> iter = aspectList.iterator(); iter.hasNext();) {
			Aspect aspect = iter.next();
			String targetClassPattern = aspect.getTargetClassPattern().replaceAll("\\$", "\\\\\\$");
			if (targetClassName.matches(targetClassPattern) == true) {
				return aspect;
			}
		}
		return null;
	}

	public static void destroy() {
		ASPECTS.clear();
	}
}
